PICの応用回路(3)  ・・・・  データロガー(その2)、温・湿度計: シリアル通信、演算法


  (2) 温・湿度計の作製:

  作製した ADコンバータ機能による マイコン電圧計を基本として、温・湿度センサのヘッドを取り付けることによって、温度計・湿度計とし、また、常時 LCDで表示すると共に、シリアル通信によって定期的に(このプログラムでは10秒ごとに)データをパソコンに取り込めるようにする。 センサとしては、他に、超音波、光、磁場、加速度、ガス濃度など、数V程度の電圧に変換できるものならば何でも扱うことができる。・・・  千差(センサ)万別(?)


  @ 温・湿度計ヘッドの作製:

  温度センサには、LM61CIZ(測定温度: −30℃〜100℃で 出力電圧0.3〜1.6V、 Vo = (10mV/℃ × T℃) + 600mV、 電源電圧(+2.7V〜+10V)によらない)を、電源電圧3.3Vで使用した。 湿度センサには、直線的な出力電圧を出す素子(CHS−GSSなど)が簡単であるが、ここでは、比較的安価な HS15P(駆動電圧: 〜1kHz・1Vの矩形波)湿度に対し 抵抗値が指数的に変化する)を用いて、同じく指数的に変化するスイッチング・ダイオード(1S1588、(注)代替品では良い指数特性が得られない)の順方向電圧-電流特性を使った オペアンプによる対数変換を用いる。
  オペアンプは、10mVまでの低電圧にも対応できるように 低オフセット電圧の NJU7032D (C−MOSオペアンプ)を用いた。
  温度、湿度共に、基本的には計算式により出力電圧を決めるが、素子などのばらつきを考え、アッテネーターを付けて微調整できるようにした。

  

  A 温度・湿度の計算法:

  温度:  アッテネーターVR(1kΩ)のセンター500Ωより、 V0 = V × 1.06 より、  T(℃) = (1.06 V − 0.6) × 100    ・・・・ (1)

      また、データロガー(電源電圧+5V)の ADコンバーターの数値: x として、 V = (5/1023)・x  ・・・・ (2)

      (2)を(1)に代入して、 T = 0.518 x − 60 ≒ (x − 116)*518/10  ・・・・ 表示用(×100)で 整数型として計算

  湿度:  HS15Pの仕様より、ダミー抵抗 R が 1kΩのとき H=88%、 10kΩのとき 68%、 100kΩのとき 45%、 1MΩのとき 26% であるが、実際組み立ててみると、直線性が良いのは 1MΩ〜100kΩ であり、実用範囲は湿度が約50%以下だった。

      1MΩと100kΩで直線をとると、 H = 38・V0 − 0.6 = 40.28・V − 0.6 = (x − 3)*197/10


  これらの整数型の計算は、そのまま計算すると 最初の掛け算が65535を超えるので、ブレセンハム(Bresenham)・アルゴリズムを用いて計算する。


  B 演算 と LCD表示のプログラム:

  LCD表示は、前回作製した API(関数群)を多少改造して用いた。 bresenham アルゴリズムのプログラムは以下の通りである。(* 湿度Hの計算は、桁数が大きくならないので、単純な整数型でも良い。: v = (v −3)*197/10; をそのまま記入)

  表示される温度の分解能は、877Aで 0〜5Vを1024分割するので、 ((100 − (−30))/(1.6 − 0.3))・(5/1024) ≒ 0.5(℃)しかない。 さらに、温度測定素子(LM61CIZ)自身のばらつきが ±2(℃) 程度あるので、これをアッテネーターで ±0.5(℃)に収めることになる。

  また、湿度センサに供給する1kHzの交流には、CCP端子からのPWM信号を用いた。水晶発振10MHz(* 実は、このために、最高速20MHzではなく 10MHzにした)から、動作周波数(×1/4=)2.5MHz=0.4μS より、1/16分周して 6.4μS、したがって、PR2 = 153、CCPR1L = 75(=PR2/2、デューティー比50%)に設定して 1.01kHz・約5Vの方形波となった。用いるときは分圧して1Vとする。(PR2は253まで、タイマー2の分周比は1/16までであって、ポストスケーラーは使えず、PR2をそれ以上にすると発振が止まる。)

 


  C シリアル通信のプログラム:


  LCDで常時表示すると共に、シリアル通信で10秒に1回 温度と湿度をパソコンの画面に表示するプログラムとする。
  シリアル通信は、一方的に送るだけの方法もあるが、ここでは本格的に、互いに相手に送信を停止・再開してもらう フロー制御(割り込みを使用する Xon/Xoff 制御(データロガーから、また、パソコンから の両方で、Xon : 送信再開要求、Xoff : 送信停止要求 を出す)で行なう。

  D-サブ・コネクタの 7pin−8pinの結線により、送信可否の通知は そのままパソコンへ返される。また、4pin−6pin−1pinの結線により、パソコンの電源オン/オフの通知がそのまま マイコン側の電源オン/オフとして認識される。
  したがって、シリアル通信の接続は、送信: TX(25p) → (レベルコンバータ ADM3202 の)T1IN(11p) → パソコンのRX、 受信: RX(26p) ← R1OUT ← パソコンのTX の実質2本だけになる。
   

  プログラムについて、

  ・ interrupt entry(c) は、割り込み要求を実行する関数で、割り込みフラグで受信を確認して 受信レジスタの信号を c にコピー(同時に、割り込みフラグをクリヤ)し、c の信号が Xon か Xoff ならば 変数 xf にコピーする。 変数 dc が16ならば、いっぱいになった受信バッファを終了する。(データが失われるがやむを得ない) 変数 c の受信バッファへの書き込み位置は 変数wp が記憶し、書き込むごとに 1 増やし、16を超えたら0に戻す。(= リング・バッファ処理) 受信バッファに12以上の信号が書き込まれたならば、Xoff を送信して、相手に停止要求する。(通常は受信バッファの3/4程度でXoffを送信する)

  ・ getchr(c) は、受信バッファに信号が入るのを待って、1つだけ読み出す。 途中で割り込みが入ると整合性が取れなくなるので、この関数を実行する場合、事前に割り込みを禁止し、事後に許可する。
  ・ putchr(c) ・・・ 1文字だけ、 put(*s) ・・・ 何文字でも良い、 は、 LCDの場合と全く同様に、書き込みに用いられる。 ・・・ ex) put("\n"): 改行

  ・ 通信速度の設定は、 ボーレート=4800 とするならば、 SPBRG = 10MHz(水晶発振周波数)/16/4800 − 1 = 128 になる。
  ・ 通信形式の設定は、送信形式: TXSTA = 00100100 で、送信許可(1)、非同期(0)、高速(1)、 受信形式: RCSTA = 10010000 で、受信許可(1)、連続受信(1)、アドレス検出無効(0)、などとなる。

 

  * 小数点を用いない単純な整数をシリアルポートに送るだけならば、 HI-TECH C PRO の標準ライブラリ(非同期シリアル分)を使うことができる。 標準ライブラリのヘッダを取り込み(#include<stdio.h> を追加)、 関数 gets : 編集可能な文字列入力、 puts : 文字列と改行の出力、 printf : 書式制御可能な文字列出力(CSV形式) の3つが使用可能。 特に、printf は、数値を文字列に変換し、あるいは、文字列をそのまま、区別して、CSV形式で送信するのによく用いられる。


  D 仮想端末の整備:

  代表的な仮想端末ソフト: Tera Term を、 http://sourceforge.jp/projects/ttssh2/ からダウンロードし、

  1) 設定 → シリアルポート で、通信速度: 4800、 データ: 8ビット、 フロー制御: Xon/Xoff に設定する。(* ただ送るだけならば、フロー制御: なし にする)
  2) 設定 → 端末 で、受信: LF (UNIX・C言語の規則)、 送信: CR+LF (Windowsの規則) を選択する。

  Tera Term に書き込まれたデータは、Excel 等の表計算ソフトに貼り付けて、記録、グラフ作製ができる。



  ● ソース:  ・・・・ 温・湿度計の全プログラムを build すると、 PIC16F877Aの プログラムメモリ: 23%、データ: 16%の使用だった。(PICC-Lite コンパイラ使用のため、最適化が行なわれていない条件で)
  * (追記) AD変換後のデータを取り出す記述を、 v=(ADRESH<<8)|ADRESL; から v=(ADRESH*256)+ADRESL; に変更します。前者は、PICのシフトレジスタの設計が悪くデータ取得ができないか不安定で、数値がふらつく原因となっている。

  


             戻る